﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO.Pipes;
using System.Linq;
using System.Net.Http.Json;
using System.Net.WebSockets;
using System.Text;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using Wpf.Model.Dto.WebSocket;
using Wpf.SharedContracts;
using System.Text.Json;

namespace Wpf.Common
{
    public class WebSocketHelper
    {
        private static ClientWebSocket _webSocket;
        private static Uri _serverUri = new Uri("ws://192.168.51.57:9528/wpf/");
        private static CancellationTokenSource _cts = new CancellationTokenSource();
        private const string PipeName = "SocketToWpfPipe";

        /// <summary>
        /// 初始化连接并启动接收消息循环
        /// </summary>
        public static async Task WebSocketInit()
        {
            _webSocket = new ClientWebSocket();

            try
            {
                await _webSocket.ConnectAsync(_serverUri, _cts.Token);
                Trace.WriteLine("WebSocket 连接成功！");

                // 启动心跳任务
                var heartbeatTask = Task.Run(HeartbeatLoop);

                // 启动接收消息循环
                var receiveTask = Task.Run(ReceiveLoop);

                await Task.WhenAll(heartbeatTask, receiveTask);
            }
            catch (Exception ex)
            {
                Trace.WriteLine($"连接错误: {ex.Message}");
                await Reconnect();
            }
            finally
            {
                _webSocket?.Dispose();
            }
        }

        /// <summary>
        /// 接收消息循环
        /// </summary>
        private static async Task ReceiveLoop()
        {
            // 使用内存流动态存储分片数据
            using var memoryStream = new MemoryStream();
            var buffer = new byte[1024];

            while (_webSocket.State == WebSocketState.Open && !_cts.IsCancellationRequested)
            {
                try
                {
                    var result = await _webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), _cts.Token);
                    if (result.MessageType == WebSocketMessageType.Close)
                    {
                        await _webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closed by server", _cts.Token);
                        break;
                    }

                    // 将片段写入内存流
                    memoryStream.Write(buffer, 0, result.Count);
                    // 检查是否接收完整个消息
                    if (result.EndOfMessage)
                    {
                        string message = Encoding.UTF8.GetString(memoryStream.GetBuffer(), 0, (int)memoryStream.Length);
                        // 处理接收到的消息
                        //string message = Encoding.UTF8.GetString(buffer, 0, result.Count);
                        try
                        {
                            var info = JsonConvert.DeserializeObject<SocketInfo>(message);
                            switch (info.Type)
                            {
                                case 1:
                                    var a = JsonConvert.DeserializeObject<WindowInfo>(info.Data);
                                    var pMessage = new PipeMessage { Data = a.Icon };
                                    byte[] bytes = System.Text.Json.JsonSerializer.SerializeToUtf8Bytes(pMessage);
                                    await SendViaNamedPipe(bytes);
                                    break;
                            }
                        }
                        catch (Exception ex)
                        {
                            Trace.WriteLine($"处理信息错误: {ex.Message}");
                        }
                        Trace.WriteLine($"收到消息: {message}");

                        // 触发事件（可选）
                        OnMessageReceived?.Invoke(message);
                        // 重置内存流（准备接收下一条消息）
                        memoryStream.SetLength(0);
                    }

                }
                catch (Exception ex)
                {
                    Trace.WriteLine($"接收消息失败: {ex.Message}");
                    break;
                }
                finally
                {

                }
            }
        }

        /// <summary>
        /// 心跳循环
        /// </summary>
        private static async Task HeartbeatLoop()
        {
            while (_webSocket.State == WebSocketState.Open && !_cts.IsCancellationRequested)
            {
                try
                {
                    var json = JsonConvert.SerializeObject(new
                    {
                        id = "123",
                        data = "heartbeat"
                    });
                    var message = new ArraySegment<byte>(Encoding.UTF8.GetBytes(json));
                    await _webSocket.SendAsync(message, WebSocketMessageType.Text, true, _cts.Token);
                    await Task.Delay(1000, _cts.Token);
                }
                catch (Exception ex)
                {
                    Trace.WriteLine($"心跳发送失败: {ex.Message}");
                    break;
                }
            }
        }

        /// <summary>
        /// 重连机制
        /// </summary>
        private static async Task Reconnect()
        {
            Trace.WriteLine("尝试重新连接...");
            _cts.Cancel();
            _webSocket?.Dispose();

            bool connected = false;
            while (!connected)
            {
                try
                {
                    _cts = new CancellationTokenSource();
                    _webSocket = new ClientWebSocket();
                    await _webSocket.ConnectAsync(_serverUri, _cts.Token);
                    Trace.WriteLine("重连成功！");
                    connected = true;

                    // 重启接收和心跳
                    await WebSocketInit();
                }
                catch (Exception ex)
                {
                    Trace.WriteLine($"重连失败: {ex.Message}");
                    await Task.Delay(3000);
                }
            }
        }

        // 定义一个消息接收事件（可选）
        public static event Action<string> OnMessageReceived;

        // 其他方法（GetChatWebSocketList等保持不变）
        public static async Task<string> GetChatWebSocketList()
        {
            using (var client = new HttpClient())
            {
                try
                {
                    var response = await client.GetStringAsync("http://192.168.50.192:9528/api/clients");
                    Trace.WriteLine("当前在线用户: " + response);
                    return response;
                }
                catch (Exception ex)
                {
                    Trace.WriteLine("获取在线用户失败: " + ex.Message);
                }
            }
            return "";
        }

        /// <summary>
        /// 通过管道通知wpf
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        private static async Task SendViaNamedPipe(byte[] data)
        {
            using (var server = new NamedPipeServerStream(PipeName, PipeDirection.Out))
            {
                await server.WaitForConnectionAsync(_cts.Token); // 异步等待连接
                await server.WriteAsync(data, 0, data.Length, _cts.Token);
                server.Disconnect();
            }
        }
    }
}
